<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\command;

use app\enum\KuaiShouEnum;
use app\enum\RedisEnum;
use app\model\BatchCreateContentModel;
use app\model\BatchCreateSchemaUriModel;
use app\model\KsAdvertiserModel;
use app\model\KsAppDspModel;
use app\model\KsAppModel;
use app\model\KsBuildProjectModel;
use app\model\KsTargetTemplateModel;
use app\model\KsUserVideoModel;
use think\console\Input;
use think\console\Output;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\facade\Db;
use think\helper\Str;

/**
 * @deprecated
 */
class KsBatchCreateContentCreateWork extends BaseWork
{
    public const REDIS_KEY = 'habo_new_media:task:ks_batch_project:' . RedisEnum::REDIS_LIST;

    protected function configure()
    {
        // 指令配置
        $this->setName('ks_batch_create_content_create_work');
        $this->setDescription('磁力引擎-批量搭建项目生成内容');
    }

    protected function execute(Input $input, Output $output)
    {
        try {
            $list = $this->_getList();

            if (! $list) {
                $output->writeln('暂无数据');
                return;
            }

            $ksAdvList = (new KsAdvertiserModel())->column('*', 'advertiser_id');
            foreach ($list as $v) {
                $num = $v['num'];
                $singleNum = $v['single_num'];
                $targetId = intval($v['target_id']);

                $targetArr = $this->_getTargetInfo($targetId);
                if (! $targetArr) {
                    $output->writeln("error:定向信息为空！target_id:{$targetId},batch_id:{$v['batch_id']}");
                    continue;
                }

                $targetArr = json_decode($targetArr['target'], true);
                /*$videoArr = array_values(json_decode($v['video_ids'], true));

                if (! $videoArr) {
                    continue;
                }*/

                $target = $this->_getAdDspTarget($targetArr, $v['advertiser_id'], $v['app_id']);
                if (! $target) {
                    $output->writeln("error:定向包为空！app_id:{$v['app_id']},batch_id:{$v['batch_id']}");
                    continue;
                }

                $isRule = (bool) $v['is_rule'];
                $codeArr = json_decode($v['schema_code'], true);
                $schemaList = $this->getSchemaUriList($v['advertiser_id'], $codeArr);

                if (! $schemaList) {
                    $output->writeln("error:直达链接列表为空！advertiser_id:{$v['advertiser_id']},batch_id:{$v['batch_id']}");
                    continue;
                }

                // 数据拼装
                $arr = [
                    'advertiser_id' => $v['advertiser_id'], // 广告主ID
                    'app_id' => $v['app_id'], // 应用ID
                    'project_id' => $v['project_id'], // 项目ID
                    'hosting_scene' => $v['scene'], // 营销场景
                    'campaign_type' => $v['campaign_type'], // 计划类型
                    'day_budget' => $v['day_budget'] * 1000, //	每日预算
                    'ocpx_action_type' => $v['ocpx_action_type'], // 优化目标
                    'schedule' => json_decode($v['schedule'], true), // 投放排期
                    'action_bar' => $v['action_bar'], // 行动号召按钮
                    'asset_mining' => (bool) $v['is_open'], //	素材挖掘
                    'bid_type' => $v['bid_type'], // 出价方式
                    'ad_dsp_target' => $target, // 定向包
                    'deep_conversion_type' => $v['deep_conversion_type'], // 深度优化目标
                    'deep_conversion_bid' => $v['deep_conversion_bid'] * 1000, // 深度优化目标出价
                    'enhance_conversion_type' => $v['enhance_conversion_type'], // 增强目标
                    'smart_cover' => (bool) $v['is_smart'], // 智能开关
                    'captions' => ! empty($v['captions']) ? array_values(array_filter(explode("\n", $v['captions']))) : [], // 作品广告语
                    'click_url' => $v['click_url'], // 第三方点击监测链接
                    'cpa_bid' => $v['cpa_bid'] * 1000,
                ];

                $allData = [];
                for ($i = 0; $i < $num; ++$i) {
                    $sceneIds = json_decode($v['scene_ids'], true);
                    // $photoIds = $this->_getVideoList($videoArr[0][$codeArr[$i]]);
                    $beginTime = $this->_getBeginTime($v['begin_time']);
                    // $projectName = $this->_getProjectName($v['project_name'], $codeArr[$i], $i, $sceneIds);
                    $nameRule = $this->_getRule($isRule, $v['unit_rule'], $v['creative_rule'], $codeArr[$i], $sceneIds);

                    if (! isset($ksAdvList[$v['advertiser_id']])) {
                        $output->writeln("error:磁力账户信息为空！advertiser_id:{$v['advertiser_id']},batch_id:{$v['batch_id']}");
                        continue;
                    }

                    $ksUserId = $ksAdvList[$v['advertiser_id']]['user_id'];
                    $photoList = $this->_getVideoListByCode($codeArr[$i], $ksUserId);
                    if (! $photoList) {
                        $output->writeln("error:获取视频为空！code:{$codeArr[$i]},batch_id:{$v['batch_id']}");
                        continue;
                    }

                    if ($singleNum <= 0) {
                        $output->writeln("error:单个视频数为0！batch_id:{$v['batch_id']}");
                        continue;
                    }

                    // 数据拼装
                    // $arr['name'] = $projectName; // 项目名称
                    $arr['begin_time'] = $beginTime; // 开始时间
                    $arr['schema_uri'] = $schemaList[$codeArr[$i]]['schema_uri']; // 直达链接/调起链接
                    $arr['scene_ids'] = $sceneIds; // 投放场景
                    $arr['name_rule'] = $nameRule; // 命名规则

                    if ($v['campaign_type'] == KuaiShouEnum::CAMPAIGN_TYPE_INSTALL) {
                        $arr['app_id'] = $v['app_id']; // 应用id
                        // 判断app是否是android
                        /*$appInfo = $this->_getKsAppInfo($v['app_id']);
                        if ($appInfo['platform'] == KsAppModel::PLATFORM_ANDROID) {
                            $arr['use_app_market'] = KsBuildProjectModel::MARKET_DISABLE; // 使用开启应用商店直投
                            if (! empty($v['app_store'])) {
                                $arr['app_store'] = json_decode($v['app_store'], true); // 应用商店直投列表
                                $arr['use_app_market'] = KsBuildProjectModel::MARKET_ENABLE; // 使用开启应用商店直投
                            }
                        }*/

                        $appInfo = $this->_getKsAppDspInfo($v['advertiser_id'], $v['app_id']);
                        if (! empty($appInfo['platform']) && Str::lower($appInfo['platform']) == Str::lower(KsAppDspModel::PLATFORM_ANDROID)) {
                            $arr['use_app_market'] = KsBuildProjectModel::MARKET_DISABLE; // 使用开启应用商店直投
                            if (! empty($v['app_store'])) {
                                $arr['app_store'] = json_decode($v['app_store'], true); // 应用商店直投列表
                                $arr['use_app_market'] = KsBuildProjectModel::MARKET_ENABLE; // 使用开启应用商店直投
                            }
                        }

                        if (! empty($appInfo['package_id'])) {
                            $arr['package_id'] = $appInfo['package_id']; // 包名
                        }
                    }

                    if (! empty($v['end_time'])) {
                        $arr['end_time'] = strtotime(strval($v['end_time'])) * 1000; // 投放结束时间
                    }

                    $newPhotoList = array_chunk($photoList, $singleNum);
                    foreach ($newPhotoList as $key => $photoInfo) {
                        $projectName = $this->_getProjectName($v['project_name'], $codeArr[$i], $i, $key, $sceneIds);
                        $arr['name'] = $projectName; // 项目名称
                        $arr['photo_infos'] = $photoInfo;

                        $allData[] = [
                            'batch_id' => $v['batch_id'],
                            'content_level' => BatchCreateContentModel::LEVEL_PROJECT,
                            'content_json' => json_encode($arr, JSON_UNESCAPED_UNICODE),
                            'parent_id' => 0,
                            'create_time' => time(),
                        ];
                    }
                }

                Db::startTrans();
                $result = $this->_insertAllContentData($allData);

                if ($result <= 0) {
                    Db::rollback();
                    $output->writeln('添加搭建数据失败');
                    continue;
                }

                $projectResult = $this->_updateProjectFinish([$v['batch_id']]);
                if (! $projectResult) {
                    Db::rollback();
                    $output->writeln('更新搭建状态失败');
                    continue;
                }

                $this->_pushRedisProjectId([$v['batch_id']]);
                Db::commit();
                $output->writeln('添加' . $v['batch_id'] . '成功');
            }
            $output->writeln('添加完成');
        } catch (\Exception $e) {
            $output->writeln($e->getMessage());
        }
    }

    /**
     * 获取uri列表.
     */
    private function getSchemaUriList(string $advertiserId, array $codes = []): array
    {
        $list = (new BatchCreateSchemaUriModel())->where('advertiser_id', $advertiserId)->whereIn('material_id', $codes)->field(true)->select()->toArray();

        if (! $list) {
            return [];
        }

        return array_column($list, null, 'material_id');
    }

    /**
     * 获取规则.
     */
    private function _getRule(bool $isRule = false, string $unitRule = '', string $creativeRule = '', string $code = '', array $sceneIds = []): array
    {
        if (! $isRule) {
            return ['rule_enable' => false];
        }

        $sceneStr = '';
        if (isset($sceneIds) && ! empty($sceneIds)) {
            $sceneStr = $this->_getSceneName($sceneIds);
        }

        $unitRule = str_replace(['{{直达链接}}', '{{日期}}', '{{投放目标}}', '{{广告位}}', '{{', '}}'], [$code, date('md'), '提升应用安装', $sceneStr, '[', ']'], $unitRule);
        $creativeRule = str_replace(['{{直达链接}}', '{{', '}}'], [$code, '[', ']'], $creativeRule);

        return [
            'rule_enable' => true,
            'unit_name_rule' => $unitRule,
            'creative_name_rule' => $creativeRule,
        ];
    }

    /**
     * 获取插屏名称.
     */
    private function _getSceneName(array $arr = []): string
    {
        $str = '';
        foreach ($arr as $v) {
            $str .= KuaiShouEnum::$sceneName[$v];
        }

        return $str;
    }

    /**
     * 获取项目名.
     */
    private function _getProjectName(string $projectName = '', string $keyWord = '', int $num = 0, int $sonNum = 0, array $sceneIds = []): string
    {
        $sceneStr = '';
        if (isset($sceneIds) && ! empty($sceneIds)) {
            $sceneStr = $this->_getSceneName($sceneIds);
        }

        return str_replace(['{{直达链接}}', '{{日期}}', '{{投放目标}}', '{{广告位}}'], [$keyWord, date('md'), '提升应用安装', $sceneStr], $projectName) . '_' . $num . '_' . $sonNum;
    }

    /**
     * 获取开始时间.
     */
    private function _getBeginTime(int $beginTime = 0)
    {
        return strtotime(strval($beginTime)) * 1000;
    }

    /**
     * 根据CODE获取视频列表.
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     * @deprecated
     */
    private function _getVideoListByCode(string $materialId = '', string $userId = ''): array
    {
        $list = (new KsUserVideoModel())->field(true)->whereLike('photo_name', $materialId . '%')->where('user_id', $userId)->select()->toArray();

        if (! $list) {
            return [];
        }
        $result = [];
        foreach ($list as $v) {
            $result[] = [
                'photo_id' => $v['photo_id'],
                'photo_orientation' => KuaiShouEnum::VIDEO_VERTICAL,
            ];
        }

        return $result;
    }

    /**
     * 获取视频列表.
     */
    private function _getVideoList(array $ids = []): array
    {
        $list = (new KsUserVideoModel())->whereIn('id', $ids)->field(true)->select()->toArray();

        if (! $list) {
            return [];
        }

        $result = [];
        foreach ($list as $v) {
            $result[] = [
                'photo_id' => $v['photo_id'],
                'photo_orientation' => KuaiShouEnum::VIDEO_VERTICAL,
            ];
        }

        return $result;
    }

    /**
     * 获取年龄.
     */
    private function _getAge(array $arr = []): array
    {
        $result = [];
        foreach ($arr as $v) {
            if ($v == 18) {
                $result[] = [
                    'min' => 18,
                    'max' => 23,
                ];
            } elseif ($v == 24) {
                $result[] = [
                    'min' => 24,
                    'max' => 30,
                ];
            } elseif ($v == 31) {
                $result[] = [
                    'min' => 31,
                    'max' => 40,
                ];
            } elseif ($v == 41) {
                $result[] = [
                    'min' => 41,
                    'max' => 49,
                ];
            } elseif ($v == 50) {
                $result[] = [
                    'min' => 50,
                    'max' => 100,
                ];
            }
        }

        return $result;
    }

    /**
     * 获取性别.
     */
    private function _getGender(int $num = 0): string
    {
        $gender = '';
        if ($num == 1) {
            $gender = 'F';
        } elseif ($num == 2) {
            $gender = 'M';
        }

        return $gender;
    }

    /**
     * 获取平台.
     */
    private function _getPlatform(string $appId = ''): array
    {
        $ksAppInfo = $this->_getKsAppInfo($appId);

        if ($ksAppInfo && $ksAppInfo['platform'] == KsAppModel::PLATFORM_ANDROID) {
            $platform = ['android' => ['min' => 3]];
        } else {
            $platform = ['ios' => ['min' => 6]];
        }

        return $platform;
    }

    private function _getDspPlatform(string $advId = '', string $appId = ''): array
    {
        $ksAppInfo = $this->_getKsAppDspInfo($advId, $appId);

        if ($ksAppInfo && Str::lower($ksAppInfo['platform']) == Str::lower(KsAppDspModel::PLATFORM_ANDROID)) {
            $platform = ['android' => ['min' => 3]];
        } else {
            $platform = ['ios' => ['min' => 6]];
        }

        return $platform;
    }

    /**
     * 获取定向包.
     */
    private function _getAdDspTarget(array $arr = [], string $advId = '', string $appId = ''): array
    {
        // $platform = $this->_getPlatform($appId);

        $platform = $this->_getDspPlatform($advId, $appId);
        $gender = $this->_getGender($arr['gender']);
        $ageRange = [];
        if (! empty($arr['ages_range'])) {
            $ageRange = $this->_getAge($arr['ages_range']);
        }
        $arr['intelli_extend'] = [];
        if (! empty($ageRange)) {
            $arr['intelli_extend']['no_age_break'] = true;
        }
        if (! empty($gender)) {
            $arr['intelli_extend']['no_gender_break'] = true;
        }
        if (! empty($arr['region']) || ! empty($arr['region_category_ids'])) {
            $arr['intelli_extend']['no_area_break'] = true;
        }
        return [
            'age' => $ageRange,
            'population' => ! empty($arr['population']) ? $arr['population'] : [],
            'exclude_population' => ! empty($arr['exclude_population']) ? $arr['exclude_population'] : [],
            'paid_audience' => ! empty($arr['paid_audience']) ? $arr['paid_audience'] : [],
            'gender' => $gender,
            'region_ids' => ! empty($arr['region']) ? $arr['region'] : [],
            'region_category_ids' => ! empty($arr['region_category_ids']) ? $arr['region_category_ids'] : [], // ?
            'region_type' => 1, // 指定地区
            'user_type' => ! empty($arr['user_type']) ? $arr['user_type'] : 0,
            'intelli_extend' => ! empty($arr['intelli_extend']) ? $arr['intelli_extend'] : [],
            'platform' => $platform,
            'filter_converted_level' => ! empty($arr['filter_converted_level']) ? $arr['filter_converted_level'] : 0,
            // 'filter_time_range' => ! empty($arr['filter_time_range']) ? $arr['filter_time_range'] : 1, // ?
            'app_interest_ids' => ! empty($arr['app_interest']) ? $arr['app_interest'] : [],
            'package_name' => ! empty($arr['app_ids']) ? $arr['app_ids'] : [], // ?
            'device_brand_ids' => ! empty($arr['device_brand_ids']) ? $arr['device_brand_ids'] : [],
            'device_brand' => ! empty($arr['device_brand']) ? $arr['device_brand'] : [],
        ];
    }

    /**
     * 获取App信息.
     */
    private function _getKsAppInfo(string $appId = ''): array
    {
        $info = (new KsAppModel())->where('app_id', $appId)->field(true)->find();

        if (! $info) {
            return [];
        }

        return $info->toArray();
    }

    /**
     * 获取App信息. -new.
     */
    private function _getKsAppDspInfo(string $advId = '', string $appId = ''): array
    {
        $info = (new KsAppDspModel())->where('advertiser_id', $advId)->where('app_id', $appId)->field(true)->find();

        if (! $info) {
            return [];
        }

        return $info->toArray();
    }

    /**
     * 获取target信息.
     */
    private function _getTargetInfo(int $id = 0): array
    {
        $info = (new KsTargetTemplateModel())->where('id', $id)->field(true)->find();

        if (! $info) {
            return [];
        }

        return $info->toArray();
    }

    /**
     * 添加redis.
     */
    private function _pushRedisProjectId(array $ids = [])
    {
        $redis = Cache::store('redis')->handler();
        foreach ($ids as $v) {
            $redis->rpush(self::REDIS_KEY, $v);
        }

        $redis->expire(self::REDIS_KEY, 7 * 24 * 3600);
    }

    /**
     * 更新项目.
     */
    private function _updateProjectFinish(array $ids = []): bool
    {
        $result = (new KsBuildProjectModel())->whereIn('batch_id', $ids)->update(['is_finish' => KsBuildProjectModel::FINISH_ENABLE, 'update_time' => time()]);
        if (! $result) {
            return false;
        }

        return true;
    }

    /**
     * 批量插入数据.
     */
    private function _insertAllContentData(array $allData = []): int
    {
        return (new BatchCreateContentModel())->insertAll($allData);
    }

    /**
     * 获取列表.
     */
    private function _getList(): array
    {
        return (new KsBuildProjectModel())->where('is_finish', KsBuildProjectModel::FINISH_DISABLE)->order('id DESC')->field(true)->select()->toArray();
    }
}
